using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class EffectManager : MonoBehaviour {
	
	private static EffectManager instance;
	public GameObject[] fxPrefabs;
	
	public static EffectManager Instance
	{
		get { return instance; }
	}
	
	public GameObject [] fxobj;
	public GameObject [] footSmoke;
	public int footSmokeMax = 5;
	GameObject footSmokePrefab;
	GameObject [] teleportEff;
	public GameObject teleportSpot;
	public GameObject teleportSpotPrefab;

	GameObject fxAvoidDeath;
	GameObject fxAvoidDeathPrefab;
	GameObject fxSkillReflect;
	GameObject fxSkillReflectPrefab;
	GameObject fxHealPrefab;
	GameObject fxDebufPrefab;
	GameObject fxMPRegenPrefab;
	GameObject fxBonusLootPrefab;
	GameObject fxDoublePrefab;
	List<GameObject> fxHealList = new List<GameObject>();
	List<GameObject> fxDebufList = new List<GameObject>();
	List<GameObject> fxMPRegenList = new List<GameObject>();
	GameObject fxBonusLoot;

	void Awake()
	{
		instance = this;
		
		footSmoke = new GameObject[footSmokeMax];
		footSmokePrefab = fxPrefabs[15];
		for(int i=0 ; i< footSmokeMax; i++)
			footSmoke[i] = Instantiate(footSmokePrefab) as GameObject;
		
		teleportEff = new GameObject[2];
		//for(int i=0; i<2;i++)
		//	teleportEff[i] = Instantiate(fxPrefabs[0]) as GameObject;   // Teleport
			
		fxobj = new GameObject[fxPrefabs.Length];

//		fxobj[4] = Instantiate(fxPrefabs[4]) as GameObject;    // FX_HitDamage
//		fxobj[9] = Instantiate(fxPrefabs[9]) as GameObject;    // Buff_EF_01
//		fxobj[11] = Instantiate(fxPrefabs[11]) as GameObject;    // dice num effect
//		fxobj[12] = Instantiate(fxPrefabs[12]) as GameObject;    // Skill Cast
//		fxobj[17] = Instantiate(fxPrefabs[17]) as GameObject;  // dicehit_CFXM3_Hit_Light_A_Air

//		fxobj[25] = Instantiate(fxPrefabs[25]) as GameObject; // fx_deth short

		CardManager.Instance.MakeCardEffect();
		BattleManager.Instance.MakeBattleEffect();
		UIManager.Instance.MakeUIEffect();
	}
	// Use this for initialization
	void Start () {

	}
	
	public GameObject GetPrefab(int index)
	{
		return fxPrefabs[index];
	}
	
	public GameObject CreateEffect(int index)
	{
		if(index >= fxPrefabs.Length)
			return null;
		
		GameObject obj = (GameObject)Instantiate(fxPrefabs[index]);
		//obj.transform.localScale = new Vector3(scaleFactor, scaleFactor, scaleFactor);
		return obj;
	}
	
	public GameObject CreateEffect(int index, Vector3 pos)
	{
		if(index >= fxPrefabs.Length)
			return null;
		
		GameObject obj = (GameObject)Instantiate(fxPrefabs[index], pos, Quaternion.identity);
		//obj.transform.localScale = new Vector3(scaleFactor, scaleFactor, scaleFactor);
		return obj;
	}
	
	public GameObject CreateEffectZ(int index, Vector3 pos )
	{
		if(index >= fxPrefabs.Length)
			return null;
		
		Vector3 newPos = new Vector3( pos.x, pos.y, fxPrefabs[index].transform.position.z);
		GameObject obj = (GameObject)Instantiate(fxPrefabs[index], newPos, Quaternion.identity);
		//obj.transform.localScale = new Vector3(scaleFactor, scaleFactor, scaleFactor);
		return obj;		
	}
	
	public GameObject CreateEffectParent(int index, Transform myparent)
	{
		if(index >= fxPrefabs.Length)
			return null;
		
		GameObject obj = (GameObject)Instantiate(fxPrefabs[index], myparent.position, Quaternion.identity);		
		obj.transform.parent = myparent;
		obj.transform.localPosition = fxPrefabs[index].transform.localPosition;
		obj.transform.localScale = fxPrefabs[index].transform.localScale;
		obj.transform.localRotation = fxPrefabs[index].transform.localRotation;
		
		return obj;
	}
	
	public GameObject NGUICreateEffect(int index, GameObject parent)
	{
		return NGUICreateEffectZ(index, parent, new Vector3(0,0,0) );
	}

	public GameObject NGUICreateEffectZ(int index, GameObject parent, Vector3 pos)
	{
		if(index >= fxPrefabs.Length)
			return null;		
		GameObject go = NGUITools.AddChild(parent, fxPrefabs[index]);
		go.transform.localPosition = new Vector3(pos.x, pos.y, fxPrefabs[index].transform.position.z );
		return go;
	}
	
	void PlayParticle(int index)
	{
		ParticleSystem ps = fxobj[index].GetComponent<ParticleSystem>();
		if(ps!=null)
		{
			ps.enableEmission = true;
			ps.Clear ();
			ps.Play ();
		}
	}
	
	public void PlayTeleportEff(int i, Vector3 pos)
	{
		if(teleportEff[i]==null)
			teleportEff[i] = Instantiate(fxPrefabs[0]) as GameObject;
		teleportEff[i].transform.position = pos;
		teleportEff[i].GetComponent<ParticleSystem>().Play ();
	}
	
	public void PlayEffectZ(int index, Vector3 pos )
	{
		if(fxobj[index]==null)
		{
			if(fxPrefabs[index]==null)
				return;
			else
				fxobj[index] = Instantiate(fxPrefabs[index]) as GameObject;
		}
		fxobj[index].gameObject.SetActive(true);
		fxobj[index].transform.position = new Vector3( pos.x, pos.y, fxPrefabs[index].transform.position.z);
		PlayParticle(index);
	}

	public void PlayEffectZParent(int index, Vector3 pos, Transform myparent )
	{
		if(fxobj[index]==null)
		{
			if(fxPrefabs[index]==null)
				return;
			else
				fxobj[index] = Instantiate(fxPrefabs[index]) as GameObject;
		}
		fxobj[index].gameObject.SetActive(true);
		fxobj[index].transform.position = new Vector3( pos.x, pos.y, fxPrefabs[index].transform.position.z);
		fxobj[index].transform.parent = myparent;
		PlayParticle(index);
	}
	
	public void  PlayEffectParent(int index, Transform myparent)
	{	
		if(fxobj[index]==null)
		{
			if(fxPrefabs[index]==null)
				return;
			else
				fxobj[index] = Instantiate(fxPrefabs[index]) as GameObject;
		}
		fxobj[index].gameObject.SetActive(true);
		fxobj[index].transform.parent = myparent;
		fxobj[index].transform.localPosition = fxPrefabs[index].transform.localPosition;
		fxobj[index].transform.localScale = fxPrefabs[index].transform.localScale;
		fxobj[index].transform.localRotation = fxPrefabs[index].transform.localRotation;
		PlayParticle(index);
	}	

	public void PlayFootSmoke(Vector3 pos)
	{
		for(int i=0; i<footSmokeMax; i++)
		{
			ParticleSystem ps = footSmoke[i].GetComponent<ParticleSystem>();
			if( !ps.isPlaying)
			{
				footSmoke[i].transform.position = new Vector3( pos.x, pos.y, footSmokePrefab.transform.position.z);
				ps.Play();
				break;
			}
		}
	}

	public void DisableParticle(int index, float delay)
	{
		StartCoroutine(CoDisableParticle(index,delay));
	}

	IEnumerator CoDisableParticle(int index, float delay)
	{
		yield return new WaitForSeconds(delay);
		fxobj[index].transform.parent = instance.transform;
		ParticleSystem ps = fxobj[index].GetComponent<ParticleSystem>();
		if(ps!=null)
		{
			ps.Stop ();
			ps.enableEmission=false;
		}
		fxobj[index].SetActive(false);
	}

	public void CreateTeleportSpotEfffect(BoardTile tile)
	{
		if(teleportSpotPrefab==null)
			teleportSpotPrefab = Resources.Load("Prefabs/FX/SFX_Teleport") as GameObject;
		if(teleportSpotPrefab!=null)
		{
			if(teleportSpot==null)
				teleportSpot = Instantiate( teleportSpotPrefab) as GameObject;
			else
				teleportSpot.SetActive(true);
			teleportSpot.transform.parent = tile.transform;
			Vector3 newPos = teleportSpotPrefab.transform.position;
			teleportSpot.transform.localPosition = newPos;

			StartCoroutine("CoDeactivateEff",teleportSpot);
		}
	}

	public void CreateBonusLootEff(BoardPerson person)
	{
		if(fxBonusLootPrefab==null)
			fxBonusLootPrefab = Resources.Load ("Prefabs/FX/card_bonus_loot_chance") as GameObject;
		if(fxBonusLootPrefab!=null)
		{
			if(fxBonusLoot==null)
				fxBonusLoot = Instantiate(fxBonusLootPrefab) as GameObject;
			fxBonusLoot.transform.parent = person.transform;
			fxBonusLoot.transform.localPosition = fxBonusLootPrefab.transform.position;
			fxBonusLoot.transform.localRotation = fxBonusLootPrefab.transform.rotation;
			fxBonusLoot.transform.localScale = fxBonusLootPrefab.transform.localScale;
			StartCoroutine("CoDeactivateEff",fxBonusLoot);
		}
	}

	IEnumerator CoDeactivateEff(GameObject go)
	{
		yield return new WaitForSeconds(3.0f);
		go.transform.parent = instance.transform;
		go.SetActive(false);
	}

	public void PlayEffect_AvoidDeath(BoardPerson person)
	{
		if(fxAvoidDeath==null)
		{
			if(fxAvoidDeathPrefab==null)
				fxAvoidDeathPrefab = Resources.Load("Prefabs/FX/SFX_AvoidDeth") as GameObject;
			if(fxAvoidDeathPrefab!=null)
				fxAvoidDeath = Instantiate(fxAvoidDeathPrefab) as GameObject;
		}

		if(fxAvoidDeath!=null)
		{
			fxAvoidDeath.transform.parent = person.transform;
			fxAvoidDeath.transform.localPosition = fxAvoidDeathPrefab.transform.position;
			fxAvoidDeath.transform.localRotation = fxAvoidDeathPrefab.transform.rotation;
			fxAvoidDeath.transform.localScale = fxAvoidDeathPrefab.transform.localScale;
			fxAvoidDeath.SetActive(true);
			StartCoroutine("CoDeactivateEff",fxAvoidDeath);
		}
	}

	public void PlayEffect_SkillReflect(BoardPerson person)
	{
		if(fxSkillReflect==null)
		{
			if(fxSkillReflectPrefab==null)
				fxSkillReflectPrefab = Resources.Load("Prefabs/FX/SFX_Reflection") as GameObject;
			if(fxSkillReflectPrefab!=null)
				fxSkillReflect = Instantiate(fxSkillReflectPrefab) as GameObject;
		}
		
		if(fxSkillReflect!=null)
		{
			fxSkillReflect.transform.parent = person.transform;
			fxSkillReflect.transform.localPosition = fxSkillReflectPrefab.transform.position;
			fxSkillReflect.transform.localRotation = fxSkillReflectPrefab.transform.rotation;
			fxSkillReflect.transform.localScale = fxSkillReflectPrefab.transform.localScale;
			fxSkillReflect.SetActive(true);
			StartCoroutine("CoDeactivateEff",fxSkillReflect);
		}
	}

	public void PlayEffect_Heal(BoardPerson person)
	{
		foreach(GameObject go in fxHealList)
		{
			if(!go.activeSelf)
			{
				ActivateHealFx(go, person);
				return;
			}
		}

		if(fxHealPrefab==null)
			fxHealPrefab = Resources.Load("Prefabs/Ingame/effect/using_ingame/Heal_EF_01") as GameObject;

		if(fxHealPrefab!=null)
		{
			GameObject newFx = Instantiate(fxHealPrefab) as GameObject;
			fxHealList.Add (newFx);
			ActivateHealFx(newFx, person);
		}
	}

	void ActivateHealFx(GameObject go, BoardPerson person)
	{
		go.transform.parent = person.transform;
		go.transform.localPosition = fxHealPrefab.transform.position;
		go.transform.localRotation = fxHealPrefab.transform.rotation;
		go.transform.localScale = fxHealPrefab.transform.localScale;
		go.SetActive(true);
		StartCoroutine("CoDeactivateEff",go);
	}

	public void PlayEffect_Debuf(BoardPerson person)
	{
		foreach(GameObject go in fxDebufList)
		{
			if(!go.activeSelf)
			{
				ActivateDebufFx(go, person);
				return;
			}
		}
		
		if(fxDebufPrefab==null)
			fxDebufPrefab = Resources.Load("Prefabs/Ingame/effect/using_ingame/Debuff_Skill_01") as GameObject;
		
		if(fxDebufPrefab!=null)
		{
			GameObject newFx = Instantiate(fxDebufPrefab) as GameObject;
			fxDebufList.Add (newFx);
			ActivateDebufFx(newFx, person);
		}
	}
	
	void ActivateDebufFx(GameObject go, BoardPerson person)
	{
		go.transform.parent = person.transform;
		go.transform.localPosition = fxDebufPrefab.transform.position;
		go.transform.localRotation = fxDebufPrefab.transform.rotation;
		go.transform.localScale = fxDebufPrefab.transform.localScale;
		go.SetActive(true);
		StartCoroutine("CoDeactivateEff",go);
	}

	public void PlayEffect_MPRegen(BoardPerson person)
	{
		foreach(GameObject go in fxMPRegenList)
		{
			if(!go.activeSelf)
			{
				ActivateMPRegenFx(go, person);
				return;
			}
		}
		
		if(fxMPRegenPrefab==null)
			fxMPRegenPrefab = Resources.Load("Prefabs/Ingame/effect/using_ingame/Mana_EF_01") as GameObject;
		
		if(fxMPRegenPrefab!=null)
		{
			GameObject newFx = Instantiate(fxMPRegenPrefab) as GameObject;
			fxMPRegenList.Add (newFx);
			ActivateMPRegenFx(newFx, person);
		}
	}
	
	void ActivateMPRegenFx(GameObject go, BoardPerson person)
	{
		go.transform.parent = person.transform;
		go.transform.localPosition = fxMPRegenPrefab.transform.position;
		go.transform.localRotation = fxMPRegenPrefab.transform.rotation;
		go.transform.localScale = fxMPRegenPrefab.transform.localScale;
		go.SetActive(true);
		StartCoroutine("CoDeactivateEff",go);
	}

	public void DoubleEffect(Vector3 newPos)
	{
		if(fxDoublePrefab==null)
			fxDoublePrefab = Resources.Load("Prefabs/FX/FX_dubble_Stars") as GameObject;
		GameObject go = Instantiate(fxDoublePrefab) as GameObject;
		go.transform.position = newPos;
		go.transform.rotation = fxDoublePrefab.transform.rotation;
		go.transform.localScale = fxDoublePrefab.transform.localScale;
		Destroy(go,3.0f);
	}
}
